﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Drawing;
using System.Timers;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_IceWall : AreaSpell
    {
        //Used to record the hex's motion type so we can set it back to normal when the spell is removed
        private List<MotionData> motionData = new List<MotionData>();
        private int getMotion(int MapX, int MapY)
        {
            foreach (MotionData motion in motionData)
            {
                if (motion.MapX == MapX && motion.MapY == MapY)
                    return motion.Motion;
            }
            return 0;
        }


        public Spell_IceWall() { }

        public void Cast(CreatureBase myCreatureBase, int CastLevel, List<string> MoveList)
        {
            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, MoveList, out MapItemsWithin12) == false)
                return;

            //Set Duration & Damage Per Character Stats
            DurationLow = 40;
            DurationHigh = 60;

            //Ice wall cannot be cast on players
            if (CastMapX == myCreatureBase.MapX && CastMapY == myCreatureBase.MapY)
                return;

            //Calculate Moves to Map Locations
            List<Point> Positions = new List<Point>();
            Positions.Add(new Point(myCreatureBase.MapX, myCreatureBase.MapY));
            Point LastPosition = new Point();
            Point NewPosition = new Point();

            LastPosition.X = myCreatureBase.MapX;
            LastPosition.Y = myCreatureBase.MapY;
            foreach (string Move in MoveList)
            {
                if (Move == "NW")
                {
                    NewPosition.X = LastPosition.X - 1;
                    NewPosition.Y = LastPosition.Y - 1;
                }
                else if (Move == "N")
                {
                    NewPosition.X = LastPosition.X - 0;
                    NewPosition.Y = LastPosition.Y - 1;
                }
                else if (Move == "NE")
                {
                    NewPosition.X = LastPosition.X + 1;
                    NewPosition.Y = LastPosition.Y - 1;
                }
                else if (Move == "E")
                {
                    NewPosition.X = LastPosition.X + 1;
                    NewPosition.Y = LastPosition.Y - 0;
                }
                else if (Move == "SE")
                {
                    NewPosition.X = LastPosition.X + 1;
                    NewPosition.Y = LastPosition.Y + 1;
                }
                else if (Move == "S")
                {
                    NewPosition.X = LastPosition.X + 0;
                    NewPosition.Y = LastPosition.Y + 1;
                }
                else if (Move == "SW")
                {
                    NewPosition.X = LastPosition.X - 1;
                    NewPosition.Y = LastPosition.Y + 1;
                }
                else if (Move == "W")
                {
                    NewPosition.X = LastPosition.X - 1;
                    NewPosition.Y = LastPosition.Y + 0;
                }
                LastPosition = NewPosition;
                Positions.Add(NewPosition);
            }

            List<MapItem> MapItemsWithin8 = new List<MapItem>();
            List<MapItem> MapItemsInPath = new List<MapItem>();
            List<Character> CharactersWithin8 = new List<Character>();
            foreach (MapItem mapitem in MapItemsWithin12)
            {
                foreach (Point point in Positions)
                {
                    if (Math.Abs(mapitem.MapX - point.X) <= 8 && Math.Abs(mapitem.MapY - point.Y) <= 8)
                    {
                        MapItemsWithin8.Add(mapitem);
                        foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                        {
                            if (creaturebase is Character)
                                CharactersWithin8.Add((Character)creaturebase);
                        }
                        break;
                    }
                }
                foreach (Point point in Positions)
                {
                    if (point.X == mapitem.MapX && point.Y == mapitem.MapY)
                    {
                        MapItemsInPath.Add(mapitem);
                        break;
                    }
                }
            }

            List<MapItem> MapItemsToCast = new List<MapItem>();
            foreach (Point point in Positions)
            {
                bool lastPosition = false;
                foreach (MapItem mapitem in MapItemsInPath)
                {
                    if (mapitem.MapX == point.X && mapitem.MapY == point.Y)
                    {
                        if (mapitem.CreaturesBases.Count > 0 || mapitem.Motion == 0)
                        {
                            lastPosition = true;
                            break;
                        }
                        else
                        {
                            MapItemsToCast.Add(mapitem);
                            if (mapitem.MapX == CastMapX && mapitem.MapY == CastMapY)
                            {
                                lastPosition = true;
                                break;
                            }
                        }
                    }
                    if (lastPosition == true)
                        break;
                }
            }
            if (MapItemsToCast.Count == 0)
                return;

            foreach (MapItem mapitem in MapItemsToCast)
            {
                mapitem.SpellLayer1.Add(this);

                MotionData md = new MotionData();
                md.MapX = mapitem.MapX;
                md.MapY = mapitem.MapY;
                md.Motion = mapitem.Motion;
                motionData.Add(md);

                mapitem.Motion = 0;
            }

            base.MapItems = MapItemsToCast;

            foreach (Character character in CharactersWithin8)
            {
                character.AddMapItems(MapItemsToCast,false);

                //Play Sound
            }

            //Start Spell Timer
            spellTimer.Start();
        }
        
        protected override void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            TimerCounter = TimerCounter + 1;
            
            //Get MapLock
            LockItem MapLock = Managers.GameHandler.GetLockItem(MapID, Instance);
            
            //Lock MapLock
            lock (MapLock.LockObj)
            {
                //Stop Running if no mapitems
                bool FoundItem = false;
                foreach (MapItem mapitem in MapItems)
                {
                    foreach (Spell spell in mapitem.SpellLayer1)
                    {
                        if (spell.SpellID == this.SpellID)
                        {
                            FoundItem = true;
                            break;
                        }
                    }
                }
                if (FoundItem == false)
                    return;

                List<MapItem> MapItemsToUpdate = new List<MapItem>();

                foreach (MapItem mapitem in MapItems)
                {
                    bool foundSpell = false;
                    foreach (Spell spell in mapitem.SpellLayer1)
                    {
                        if (spell.SpellID == this.SpellID)
                        {
                            foundSpell = true;
                            break;
                        }
                    }
                    if (foundSpell == false)
                        continue;

                    if (TimerCounter >= DurationLow)
                    {
                        int RemoveSpell = Managers.GameHandler.random.Next(-1, DurationHigh - TimerCounter);
                        if (RemoveSpell == -1 || TimerCounter >= DurationHigh)
                        {
                            mapitem.SpellLayer1.Remove(this);
                            mapitem.Motion = getMotion(mapitem.MapX, mapitem.MapY);
                            MapItemsToUpdate.Add(mapitem);
                        }
                    }
                }

                if (MapItemsToUpdate.Count > 0)
                {
                    //Get Map
                    Map CurrentMap = Managers.GameHandler.GetMap(MapID, Instance);
                    List<Character> CharsToUpdate = new List<Character>();
                    //Send Updated Hexes to all characters within 8 of any hex effected
                    foreach (MapItem mapitem in CurrentMap.MapItems)
                    {
                        foreach (MapItem mitem in MapItems)
                        {
                            if (mapitem.MapX - mitem.MapX >= -4 && mapitem.MapX - mitem.MapX <= 4 && mapitem.MapY - mitem.MapY >= -4 && mapitem.MapY - mitem.MapY <= 4)
                            {
                                foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                                {
                                    if (creatureBase is Character)
                                        CharsToUpdate.Add((Character)creatureBase);
                                }
                                break;
                            }
                        }
                    }
                    foreach (Character character in CharsToUpdate)
                    {
                        character.AddMapItems(MapItemsToUpdate, false);
                    }
                }
            }
            spellTimer.Start();
        }
    }

    
}
